'use strict';
var u = Object.defineProperty;
var f = (t, e, s) =>
  e in t
    ? u(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s })
    : (t[e] = s);
var c = (t, e, s) => (f(t, typeof e != 'symbol' ? e + '' : e, s), s);
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const p = require('../doc/directives.cjs'),
  E = require('../doc/Document.cjs'),
  a = require('../errors.cjs'),
  l = require('../nodes/identity.cjs'),
  g = require('./compose-doc.cjs'),
  v = require('./resolve-end.cjs');
function h(t) {
  if (typeof t == 'number') return [t, t + 1];
  if (Array.isArray(t)) return t.length === 2 ? t : [t[0], t[1]];
  const { offset: e, source: s } = t;
  return [e, e + (typeof s == 'string' ? s.length : 1)];
}
function m(t) {
  var o;
  let e = '',
    s = !1,
    r = !1;
  for (let i = 0; i < t.length; ++i) {
    const n = t[i];
    switch (n[0]) {
      case '#':
        (e +=
          (e === ''
            ? ''
            : r
              ? `

`
              : `
`) + (n.substring(1) || ' ')),
          (s = !0),
          (r = !1);
        break;
      case '%':
        ((o = t[i + 1]) == null ? void 0 : o[0]) !== '#' && (i += 1), (s = !1);
        break;
      default:
        s || (r = !0), (s = !1);
    }
  }
  return { comment: e, afterEmptyLine: r };
}
class y {
  constructor(e = {}) {
    c(this, 'directives');
    c(this, 'doc', null);
    c(this, 'options');
    c(this, 'atDirectives', !1);
    c(this, 'prelude', []);
    c(this, 'errors', []);
    c(this, 'warnings', []);
    c(this, 'onError', (e, s, r, o) => {
      const i = h(e);
      o
        ? this.warnings.push(new a.YAMLWarning(i, s, r))
        : this.errors.push(new a.YAMLParseError(i, s, r));
    });
    (this.directives = new p.Directives({ version: e.version || '1.2' })),
      (this.options = e);
  }
  decorate(e, s) {
    const { comment: r, afterEmptyLine: o } = m(this.prelude);
    if (r) {
      const i = e.contents;
      if (s)
        e.comment = e.comment
          ? `${e.comment}
${r}`
          : r;
      else if (o || e.directives.docStart || !i) e.commentBefore = r;
      else if (l.isCollection(i) && !i.flow && i.items.length > 0) {
        let n = i.items[0];
        l.isPair(n) && (n = n.key);
        const d = n.commentBefore;
        n.commentBefore = d
          ? `${r}
${d}`
          : r;
      } else {
        const n = i.commentBefore;
        i.commentBefore = n
          ? `${r}
${n}`
          : r;
      }
    }
    s
      ? (Array.prototype.push.apply(e.errors, this.errors),
        Array.prototype.push.apply(e.warnings, this.warnings))
      : ((e.errors = this.errors), (e.warnings = this.warnings)),
      (this.prelude = []),
      (this.errors = []),
      (this.warnings = []);
  }
  streamInfo() {
    return {
      comment: m(this.prelude).comment,
      directives: this.directives,
      errors: this.errors,
      warnings: this.warnings,
    };
  }
  *compose(e, s = !1, r = -1) {
    for (const o of e) yield* this.next(o);
    yield* this.end(s, r);
  }
  *next(e) {
    switch (
      (process.env.NODE_ENV === 'development' &&
        console.dir(e, { depth: null }),
      e.type)
    ) {
      case 'directive':
        this.directives.add(e.source, (s, r, o) => {
          const i = h(e);
          (i[0] += s), this.onError(i, 'BAD_DIRECTIVE', r, o);
        }),
          this.prelude.push(e.source),
          (this.atDirectives = !0);
        break;
      case 'document': {
        const s = g.composeDoc(this.options, this.directives, e, this.onError);
        this.atDirectives &&
          !s.directives.docStart &&
          this.onError(
            e,
            'MISSING_CHAR',
            'Missing directives-end/doc-start indicator line',
          ),
          this.decorate(s, !1),
          this.doc && (yield this.doc),
          (this.doc = s),
          (this.atDirectives = !1);
        break;
      }
      case 'byte-order-mark':
      case 'space':
        break;
      case 'comment':
      case 'newline':
        this.prelude.push(e.source);
        break;
      case 'error': {
        const s = e.source
            ? `${e.message}: ${JSON.stringify(e.source)}`
            : e.message,
          r = new a.YAMLParseError(h(e), 'UNEXPECTED_TOKEN', s);
        this.atDirectives || !this.doc
          ? this.errors.push(r)
          : this.doc.errors.push(r);
        break;
      }
      case 'doc-end': {
        if (!this.doc) {
          const r = 'Unexpected doc-end without preceding document';
          this.errors.push(new a.YAMLParseError(h(e), 'UNEXPECTED_TOKEN', r));
          break;
        }
        this.doc.directives.docEnd = !0;
        const s = v.resolveEnd(
          e.end,
          e.offset + e.source.length,
          this.doc.options.strict,
          this.onError,
        );
        if ((this.decorate(this.doc, !0), s.comment)) {
          const r = this.doc.comment;
          this.doc.comment = r
            ? `${r}
${s.comment}`
            : s.comment;
        }
        this.doc.range[2] = s.offset;
        break;
      }
      default:
        this.errors.push(
          new a.YAMLParseError(
            h(e),
            'UNEXPECTED_TOKEN',
            `Unsupported token ${e.type}`,
          ),
        );
    }
  }
  *end(e = !1, s = -1) {
    if (this.doc)
      this.decorate(this.doc, !0), yield this.doc, (this.doc = null);
    else if (e) {
      const r = Object.assign({ _directives: this.directives }, this.options),
        o = new E.Document(void 0, r);
      this.atDirectives &&
        this.onError(
          s,
          'MISSING_CHAR',
          'Missing directives-end indicator line',
        ),
        (o.range = [0, s, s]),
        this.decorate(o, !1),
        yield o;
    }
  }
}
exports.Composer = y;
